package com.itheima.comment.server.impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.common.VO.ApCommentVo;
import com.heima.model.common.comment.pojos.ApComment;
import com.heima.model.common.comment.pojos.ApCommentLike;
import com.heima.model.common.dtos.CommentDTO;
import com.heima.model.common.dtos.CommentLikeDTO;
import com.heima.model.common.dtos.CommentSaveDTO;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.mess.app.NewBehaviorDTO;
import com.heima.model.common.threadlocal.AppThreadLocalUtils;
import com.heima.model.common.user.pojo.ApUser;
import com.itheima.aliyun.scan.GreenScan;
import com.itheima.aliyun.scan.ScanResult;
import com.itheima.comment.server.CommentHotService;
import com.itheima.comment.server.CommentService;
import com.itheima.common.constants.article.HotArticleConstants;
import com.itheima.common.exception.CustException;
import com.itheima.feigns.UserFeign;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.statement.select.Limit;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private GreenScan greenScan;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    CommentHotService commentHotService;
    @Autowired
    RedissonClient redisson;
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public ResponseResult saveComment(CommentSaveDTO dto) {
        String content = dto.getContent();
        //远程查询当前登录用户信息
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApUser apUser = userFeign.findUserById(user.getId()).getData();
        //阿里云检测内容是否违规
        try {
            ScanResult scanResult = greenScan.greenTextScan(content);
            String suggestion = scanResult.getSuggestion();
            if (suggestion.equals("block")){//评论内容违规  替换为**
                String filteredContent = scanResult.getFilteredContent();
                ApComment apComment = new ApComment();
                apComment.setAuthorId(apUser.getId());
                apComment.setAuthorName(apUser.getName());
                apComment.setArticleId(dto.getArticleId());
                apComment.setType((short)0);
                apComment.setContent(filteredContent);
                apComment.setImage(apUser.getImage());
                apComment.setLikes(0);
                apComment.setReply(0);
                apComment.setFlag((short)0);
                apComment.setCreatedTime(new Date());
                ApComment save = mongoTemplate.save(apComment);
                return ResponseResult.okResult();

            }else{
                //内容没有问题
                String filteredContent = scanResult.getFilteredContent();
                ApComment apComment = new ApComment();
                apComment.setAuthorId(apUser.getId());
                apComment.setAuthorName(apUser.getName());
                apComment.setArticleId(dto.getArticleId());
                apComment.setType((short)0);
                apComment.setContent(dto.getContent());
                apComment.setImage(apUser.getImage());
                apComment.setLikes(0);
                apComment.setReply(0);
                apComment.setFlag((short)0);
                apComment.setCreatedTime(new Date());
                ApComment save = mongoTemplate.save(apComment);
                return ResponseResult.okResult();
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("阿里云文本审核出现异常 , 原因:{}",e.getMessage());
        }
        NewBehaviorDTO mess = new NewBehaviorDTO();
        mess.setType(NewBehaviorDTO.BehaviorType.COMMENT);
        mess.setArticleId(dto.getArticleId());
        mess.setAdd(1);
        rabbitTemplate.convertAndSend(HotArticleConstants.HOT_ARTICLE_SCORE_BEHAVIOR_QUEUE, JSON.toJSONString(mess));
        log.info("评论 发送消息 ==>{}", JSON.toJSONString(mess));
        return ResponseResult.okResult();
    }
    @Override
    public ResponseResult findByArticleId(CommentDTO dto) {
        //根据条件查询评论列表
        Date minDate = dto.getMinDate();
        if (minDate==null){
            minDate=new Date();
        }
        Integer size = dto.getSize();
        if (size==null || size==0){
            size=10;
        }
        //2 查询Mongo文章所有评论列表
        List<ApComment> apComments = null;
        Query query = Query.query(Criteria.where("articleId").is(dto.getArticleId()).and("createdTime").lt(minDate).and("flag").is(0));
        Query queryHot = Query.query(Criteria.where("articleId").is(dto.getArticleId()).and("flag").is(1));

        Sort sortTime = Sort.by(Sort.Direction.DESC,"createdTime");
        Sort sortLikes = Sort.by(Sort.Direction.DESC,"likes");
        if(dto.getIndex().intValue() == 1){ // 判断当前是否是第一页评论
            // 先查询热点评论集合  （最多5条） (条件: flag=1, 文章id, 点赞降序)
            queryHot.with(sortLikes);
            apComments = mongoTemplate.find(queryHot, ApComment.class);
            // 新size = size - 热评数量
            size=size-apComments.size();
            // 查询第一页剩余普通评论 (条件: 文章id, flag=0, 时间降序, limit:新size)
            Pageable pageable = PageRequest.of(0, size);  // page=0 第一页
            query.with(pageable);
            query.with(sortTime);
            List<ApComment> apCommentsNomal = mongoTemplate.find(query, ApComment.class);
            // 合并 热点评论  普通评论   热点list.addAll(普通list)
            apComments.addAll(apCommentsNomal);
        }else {
            // 不是第一页直接查询普通评论
            query.with(sortTime);
            Pageable pageable = PageRequest.of(0, size);  // page=0 第一页
            query.with(pageable);
            apComments = mongoTemplate.find(query, ApComment.class);
            // (条件: 文章id,flag=0,createdTime小于最小时间,时间降序,limit:size)
        }
        //判断用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            //没有登录直接返回评论列表
            return ResponseResult.okResult(apComments);
        }
        //登录了进行转换
        ArrayList<ApCommentVo> apCommentVos = new ArrayList<>();
        for (ApComment apComment : apComments) {

            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(apComment, apCommentVo);
            //查询用户点赞过哪些评论
            ApCommentLike one = mongoTemplate.findOne(Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId()).and("operation").is((short) 0)), ApCommentLike.class);
            if (one!=null){
                apCommentVo.setOperation((short)0);
            }
            apCommentVos.add(apCommentVo);
        }
        return ResponseResult.okResult(apCommentVos);
    }

    @Override
    public ResponseResult like(CommentLikeDTO dto) {
        //获得用户id
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }

        //根据评论id查询评论数据
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(dto.getCommentId())), ApComment.class);
        if (apComment==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"评论去二次元了,你也要去吗,我开车创死你");
        }
        RLock lock = redisson.getLock("likes-lock");

        try {
            if (dto.getOperation().equals((short)0)){//点赞操作
                //判断是否已经点赞
                ApCommentLike apCommentLike = mongoTemplate.findOne(Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(dto.getCommentId()).and("operation").is((short) 0)), ApCommentLike.class);
                if (apCommentLike==null){
                    //保存点赞信息
                    apCommentLike = new ApCommentLike();
                    apCommentLike.setCommentId(dto.getCommentId());
                    apCommentLike.setOperation((short)0);
                    apCommentLike.setAuthorId(user.getId());
                    ApCommentLike save = mongoTemplate.save(apCommentLike);
                    //修改评论信息的点赞数量+1
                    Update update = new Update();
                    update.set("likes",apComment.getLikes()+1);
                    mongoTemplate.updateMulti(Query.query(Criteria.where("_id").is(dto.getCommentId())),update,ApComment.class);


                }
    //            else {
    //                CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"别点那么快嘛,人家傻fufu反应不过来");
    //            }
            }else {
                //删除点赞信息
                mongoTemplate.remove(Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(dto.getCommentId()).and("operation").is((short) 0)), ApCommentLike.class);
                //修改评论信息的点赞数量-1
                Update update = new Update();
                update.set("likes",apComment.getLikes()-1);
                mongoTemplate.updateMulti(Query.query(Criteria.where("_id").is(dto.getCommentId())),update,ApComment.class);
            }
        } finally {
            lock.unlock();
        }
        //最后再查一次点赞数量
        ApComment apCommentLast = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(dto.getCommentId())), ApComment.class);
        Integer likes = apCommentLast.getLikes();
        Short flag = apCommentLast.getFlag();
        if (likes>=10 && flag.equals((short)0)){
            commentHotService.hotCommentExecutor(apComment);
        }
        HashMap<String, Integer> resultMap = new HashMap<>();
        resultMap.put("likes",likes);
        return ResponseResult.okResult(resultMap);
    }
}
